package br.ucb.cesbdao.servicos;
/*		
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

/**
 *
 * @author Gabriel
 */
public class DateUtil {
	
    private static final long MILESIMOS_POR_DIA = 24 * 60 * 60 * 1000;
    private static final long MILESIMOS_POR_HORA = 60 * 60 * 1000;

    public static final String DATA_POR_EXTENSO = "dd 'de' MMMM 'de' yyyy";
    public static final String FORMATO_PADRAO = "dd/MM/yyyy";
    public static final String FORMATO_DATA_HORA = "dd/MM/yyyy HH:mm";
    public static final String FORMATO_HORA = "HH:mm";


    public static final String STR_MES_JANEIRO = "Janeiro";
    public static final String STR_MES_FEVEREIRO = "Fevereiro";
    public static final String STR_MES_MARCO = "Março";
    public static final String STR_MES_ABRIL = "Abril";
    public static final String STR_MES_MAIO = "Maio";
    public static final String STR_MES_JUNHO = "Junho";
    public static final String STR_MES_JULHO = "Julho";
    public static final String STR_MES_AGOSTO = "Agosto";
    public static final String STR_MES_SETEMBRO = "Setembro";
    public static final String STR_MES_OUTUBRO = "Outubro";
    public static final String STR_MES_NOVEMBRO = "Novembro";
    public static final String STR_MES_DEZEMBRO = "Dezembro";

    private static final Map<Integer, String> MESES_MAP = new HashMap<Integer, String>();
    private static final String FORMATO_DATA_HORA_SEM_SEPARADORES = "yyyyMMddHHmmss";
    private static final String FORMATO_DATA_SEM_SEPARADORES = "yyyyMMdd";


    private static final Map<String, SimpleDateFormat> FORMATOS
            = new HashMap<String, SimpleDateFormat>();

    public static final String DATA_HORA = "dd/MM/yyyy HH:mm:ss";
	public static final String HORA_INICIO_DIA = " 00:00:00";
	public static final String HORA_FIM_DIA = " 23:59:59";
	public static final String DATA = "dd/MM/yyyy";

	public static final SimpleDateFormat FORMATO_DATA = new SimpleDateFormat(DATA_HORA);
	public static final SimpleDateFormat FORMATO_DATA_SIMPLES = new SimpleDateFormat(DATA);

	/**
	 * Instância de Locale com as confiurações específicas do Brasil
	 *
	 * @since 1.0
	 */
	public static final Locale LOCALE_BRASIL;

	/**
	 * Instância de TimeZone com as configurações específicas do Brasil
	 *
	 * @since 1.0
	 */
	public static final TimeZone TIME_ZONE_PADRAO_BRASIL;

	/**
	 * Instância de SimpleDateFormat configurado para o padrão "dd/mm/yyyy" e
	 * com o LACALE_BRASIL
	 *
	 * @since 1.0
	 */
	private static SimpleDateFormat SIMPLE_DATE_FORMAT_BRASIL;

	/**
	 * String com o valor da tabela ISO que define o Brasil
	 *
	 * @since 1.0
	 */
	public static final String ISO_COUNTRY_BRASIL = "BR";

	/**
	 * String com o valor da tabela ISO que define a língua portuguesa
	 *
	 * @since 1.0
	 */
	public static final String ISO_LANGUAGE_BRASIL = "pt";

	/**
	 * String com o valor GMT para o fuso horário padrão do Brasil
	 *
	 * @since 1.0
	 */
	public static final String GMT_PADRAO_BRASIL = "GMT-3:00";

	/**
	 * String com o valor GMT para o fuso horário de Fernando de Noronha
	 *
	 * @since 1.0
	 */
	public static final String GMT_FERNANDO_NORONHA = "GMT-2:00";

	/**
	 * String com o valor GMT para o fuso horário padrão da Região Amzônica
	 *
	 * @since 1.0
	 */
	public static final String GMT_AMAZONIA = "GMT-4:00";

	/**
	 * Valor referente aos mile-segundos de um dia (24 horas)
	 *
	 * @since 1.0
	 */
	public static final long TEMPO_24_HRS = (1000 * 60 * 60 * 24);
	/**
	 * @since 1.0
	 */
	public static final int JANEIRO = 0;
	/**
	 * @since 1.0
	 */
	public static final int FEVEREIRO = 1;
	/**
	 * @since 1.0
	 */
	public static final int MARCO = 2;
	/**
	 * @since 1.0
	 */
	public static final int ABRIL = 3;
	/**
	 * @since 1.0
	 */
	public static final int MAIO = 4;
	/**
	 * @since 1.0
	 */
	public static final int JUNHO = 5;
	/**
	 * @since 1.0
	 */
	public static final int JULHO = 6;
	/**
	 * @since 1.0
	 */
	public static final int AGOSTO = 7;
	/**
	 * @since 1.0
	 */
	public static final int SETEMBRO = 8;
	/**
	 * @since 1.0
	 */
	public static final int OUTUBRO = 9;
	/**
	 * @since 1.0
	 */
	public static final int NOVEMBRO = 10;
	/**
	 * @since 1.0
	 */
	public static final int DEZEMBRO = 11;

	/**
	 * @since 1.0
	 */
	public static final int SEGUNDOS = 0;
	/**
	 * @since 1.0
	 */
	public static final int MINUTOS = 1;
	/**
	 * @since 1.0
	 */
	public static final int HORAS = 2;
	/**
	 * @since 1.0
	 */
	public static final int DIAS = 3;
	/**
	 * @since 1.0
	 */
	public static final int MESES = 4;
	/**
	 * @since 1.0
	 */
	public static final int ANOS = 5;

	/**
	 * @since 1.0
	 */
	private static final int INCREMENTO = 0;

	/**
	 * @since 1.0
	 */
	private static final int DECREMENTO = 1;

	/**
	 * String correspondente Ã  segunda-feira
	 *
	 * @since 1.2
	 */
	public static final String STR_SEGUNDA_FEIRA = "segunda-feira";

	/**
	 * String correspondente Ã  terça-feira
	 *
	 * @since 1.2
	 */
	public static final String STR_TERCA_FEIRA = "terça-feira";

	/**
	 * String correspondente Ã  quarta-feira
	 *
	 * @since 1.2
	 */
	public static final String STR_QUARTA_FEIRA = "quarta-feira";

	/**
	 * String correspondente Ã  quita-feira
	 *
	 * @since 1.2
	 */
	public static final String STR_QUINTA_FEIRA = "quinta-feira";

	/**
	 * String correspondente Ã  sexta-feira
	 *
	 * @since 1.2
	 */
	public static final String STR_SEXTA_FEIRA = "sexta-feira";

	/**
	 * String correspondente ao sábado
	 *
	 * @since 1.2
	 */
	public static final String STR_SABADO = "sábado";

	/**
	 * String correspondente ao domingo
	 *
	 * @since 1.2
	 */
	public static final String STR_DOMINGO = "domingo";

	/*
	 * Inicializa as constante de localização (LACALE_BRASIL e TIME_ZONE_BRASIL)
	 * e define os valores padrões de localização para o sistema.
	 */
        static {
            FORMATOS.put(FORMATO_PADRAO, new SimpleDateFormat(FORMATO_PADRAO));
            FORMATOS.put(FORMATO_DATA_HORA, new SimpleDateFormat(FORMATO_DATA_HORA));
            FORMATOS.put(FORMATO_HORA, new SimpleDateFormat(FORMATO_HORA));
                    // Inicializa o Locale padrão do sistema
                    LOCALE_BRASIL = new Locale(ISO_LANGUAGE_BRASIL, ISO_COUNTRY_BRASIL);

                    // Inicializa o TimeZone padrão do sistema
                    TIME_ZONE_PADRAO_BRASIL = TimeZone.getTimeZone(GMT_PADRAO_BRASIL);

                    // Define o TimeZone padrão do sistema
//                    TimeZone.setDefault(TIME_ZONE_PADRAO_BRASIL);
        }

    public static boolean equalsSemHoras(Date d1, Date d2) {
        return getAno(d1).equals(getAno(d2)) && getMes(d1).equals(getMes(d2)) && getDia(d1).equals(getDia(d2));
    }

    public static Date getDiaInicioMes(Integer mes, Integer ano) {
        return new GregorianCalendar(ano, mes-1, 1).getTime();
    }

    public static Date getDiaFinalMes(Integer mes, Integer ano) {
        return decrementaDia(new GregorianCalendar(ano, mes, 1).getTime(), 1);
    }

    public static Date criarDataAtualSemHora(int dia, int mes, int ano) {
        return new GregorianCalendar(ano, mes-1, dia).getTime();
    }

    public static Date getPrimeiroDiaDoAno(int ano){
        return criarDataAtualSemHora(1, 1, ano);
    }

    public static Date getUltimoDiaDoAno(int ano){
        return criarDataAtualSemHora(31, 12, ano);
    }

    public static Date getUltimoDiaDoMes(int mes, int ano) {
        return criarDataAtualSemHora(getDiasMes(mes, ano), mes, ano);
    }

    public static Date getPrimeiroDiaDoMes(int mes, int ano) {
        return criarDataAtualSemHora(1, mes, ano);
    }

	/**
	 * Construtor para impedir a instanciação da classe utilitária.
	 *
	 */
	private DateUtil() {

	}

	/**
	 * Faz o parse de uma data em formato padrão (dd/mm/aaaa).
	 *
	 * @param data String contendo a data.
	 *
	 * @return Objeto contendo a data.
	 */
	public static Date parseData(String data) {
		if (data!=null&&!data.isEmpty()){
			return parseData(data, FORMATO_PADRAO);
		}
		return null;
	}

	/**
	 * Faz o parse de uma data em formato padrão (dd/mm/aaaa hh:mm).
	 *
	 * @param data String contendo a data.
	 *
	 * @return Objeto contendo a data.
	 */
	public static Date parseDataHora(String data) {
		return parseData(data, FORMATO_DATA_HORA);
	}

	/**
	 * Formata uma data com o texto de sua hora no formato padrão (HH:MM).
	 *
	 * @param data Date a ser formatada.
	 *
	 * @return Representação textual da hora.
	 */
	public static String formataHora(Date data) {
		return formataData(data, FORMATO_HORA);
	}

	/**
	 * Formata uma data como texto em formato padrão (dd/mm/aaaa).
	 *
	 * @param data Data a ser formatada.
	 *
	 * @return Representação textual da data.
	 */
    public static String formataData(Date data) {
        return formataData(data, FORMATO_PADRAO);
    }

    /**
	 * Formata uma data como texto em formato padrão (dd/mm/aaaa).
	 *
	 * @param data Data a ser formatada.
	 *
	 * @return Representação textual da data.
	 */
    public static String formatarData(Date data) {
    	if (data == null) {
    		return null;
    	}
    	return formataData(data);
    }

    public static Date formatarDataPadrao(Date data){
    	String dataStr = formataData(data);
    	Date dataRetorno = parseData(dataStr, FORMATO_PADRAO);
    	return dataRetorno;
    }

	/**
	 * Faz o parse da data no formato informado.
	 *
	 * @param data Data a ser convertida.
	 * @param formato Formato a ser usado.
	 *
	 * @return Objeto data.
	 */
	public static Date parseData(String data, String formato) {
		try {
			return getFormato(formato).parse(data);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Formata a data no formato informado.
	 *
	 * @param data Data a ser convertida.
	 * @param formato Formato a ser usado.
	 *
	 * @return Representação textual da data.
	 */
	public static String formataData(Date data, String formato) {
		return getFormato(formato).format(data);
	}

    /**
     * Obtém um formato a partir do padrão informado.
     *
     * @param padrao Padrão que servirá para o formato.
     *
     * @return formato.
     */
    private static SimpleDateFormat getFormato(String padrao) {
        SimpleDateFormat formato = FORMATOS.get(padrao);
        if (formato == null) {
            formato = new SimpleDateFormat(padrao);
            FORMATOS.put(padrao, formato);
        }
        return formato;
    }

    /**
     * Calcula a diferenca em dias entre duas datas.
     *
     * @param dataInicio Data de início.
     * @param dataFim Data fim.
     *
     * @return diferença em dias.
     */
    public static int diferenca(Date dataInicio, Date dataFim) {
        double diferenca = dataFim.getTime() - dataInicio.getTime();
        return new Long(Math.round((diferenca / MILESIMOS_POR_DIA))).intValue();
    }
    public static int diferencaEmHoras(Date dataInicio, Date dataFim) {
        double diferenca = dataFim.getTime() - dataInicio.getTime();
        return new Long(Math.round((diferenca / MILESIMOS_POR_HORA))).intValue();
    }

    /**
     * Retorna true caso a data esteja dentro do periodo.
     *
     * @param data Date Data a ser analisada dentro do intervalo.
     * @param dataInicial Date Data inicial do periodo.
     * @param dataFinal Date Data final do período.
     *
     * @return true ou false.
     */
    public static boolean dataEntrePeriodo(Date data, Date dataInicial, Date dataFinal){
    	return (data.compareTo(dataInicial) != -1 && data.compareTo(dataFinal) < 1) ? true : false;
    }

    /**
     * Cria um objeto do tipo Calendar com a data especificada.
     *
     * @param data Data do calendário.
     *
     * @return Calendário.
     */
    public static Calendar criarCalendario(Date data) {

        Calendar calendario = Calendar.getInstance();
        calendario.setTime(data);
        return calendario;

    }

    /**
     * Retorna a data sem as horas.
     *
     * @return Date
     */
    public static Date criarDataAtualSemHora(){
    	String dataFormatada = formataData(new Date());
    	return parseData(dataFormatada);
    }

    /**
     * Retorna a data atual do sistema
     *
     * @return Date
     */
    public static Date getDataAtual() {
        return Calendar.getInstance().getTime();
    }

    /**
     * Valida se a data é mairo do que noventa dias.
     *
     * @param dataInicio - Date data início.
     * @param dataFim - Date data fim.
     *
     * @return boolean - Indica se a data é ou não maior que noventa dias.
     */
    public static boolean isDataMaiorNoventaDias(Date dataInicio, Date dataFim){
    	if ((dataInicio == null) || (dataFim == null)) {
    		return false;
    	}
    	return (diferenca(dataInicio, dataFim) > 89);
    }

    /**
     * Diminiu a quantidade de dias.
     *
     * @param data - Data a diminuir os dias.
     * @param qtdDias - Inteiro que indica a quantidade de dias a diminuir na data.
     *
     * @return Date - Nova data.
     */
    public static Date diminuirDias(Date data, int qtdDias){
    	Calendar calendario = criarCalendario(data);
        calendario.add(Calendar.DAY_OF_MONTH, -qtdDias);
    	return calendario.getTime();
    }

    /**
     * Aumenta a quantidade de dias.
     *
     * @param data - Data a aumentar a quantidade de dias.
     * @param qtdDias - Quantidade de dias a aumentar.
     *
     * @return Date - nova data.
     */
    public static Date aumentarDias(Date data, int qtdDias){
    	if (data == null) {
    		return data;
    	}
    	Calendar calendario = criarCalendario(data);
        calendario.add(Calendar.DAY_OF_MONTH, qtdDias);
    	return calendario.getTime();
    }

    /**
     * Compara duas datas retirando as horas para saber se são iguais.
     *
     * @param dataA data a ser comparada.
     * @param dataB data a ser comparada.
     *
     * @return boolean verdadeira caso sejam iguais ou falso para o contrario.
     */
    public static boolean isDataIgual(Date dataA, Date dataB){
    	return retirarHora(dataA).compareTo(retirarHora(dataB)) == 0;
    }

    /**
     * Compara duas datas para saber se os meses são iguais.
     *
     * @param dataA data a ser comparada.
     * @param dataB data a ser comparada.
     *
     * @return boolean verdadeira caso os meses sejam iguais ou falso para o contrario.
     */
    public static boolean isMesIgual(Date dataA, Date dataB){
    	return getMes(dataA).intValue() == getMes(dataB).intValue() ;
    }

    /**
     * Metodo utilizado para retirar a hora, minuto e segundo da data
     * @param data Data para retirar a hora
     * @return retorna data sem hora.
     */
    public static Date retirarHora(Date data){
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(data);
    	calendar.set(Calendar.HOUR, 0);
    	calendar.set(Calendar.MINUTE, 0);
    	calendar.set(Calendar.SECOND, 0);
    	return calendar.getTime();
    }

    /**
     * Retorna o ano atual.
     *
     * @return Ano atual.
     */
    public static Short getAnoAtual() {
    	return (short) Calendar.getInstance().get(Calendar.YEAR);
    }

    /**
     * Retorna o mês da data informada.
     *
     * @param data - Objeto que possui a data a retirar o mês desejado.
     *
     * @return Mês obtido da data.
     */
    public static Integer getMes(Date data) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(data);
    	return calendar.get(Calendar.MONTH)+1;
    }

    public static Integer getDia(Date data) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(data);
    	return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * Retorna o ano conforme da data passada como parametro.
     *
     * @param date - Objeto que possui o ano a obter.
     *
     * @return Ano obtido da data.
     */
    public static Integer getAno(Date date) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
    	return calendar.get(Calendar.YEAR);
    }


    /**
     * Obtém o nome do mês conforme a chave indicada.
     *
     * @param chave - Chave que representa o mês a obter a descrição.
     *
     * @return Descrição do mês.
     */
    public static String getNomeMes(int chave) {
    	loadDescricaoMeses();
    	return MESES_MAP.get(chave);
    }
    /**
     * Obtém o nome do mês conforme a data indicada.
     *
     * @param Data - data que representa o mês a obter a descrição.
     *
     * @return Descrição do mês.
     */
    public static String getNomeMes(Date date) {
    	
    	return getNomeMes(getMes(date)-1);
    }

    /**
     * Obtém uma map com as descrições dos meses.
     */
    private static void loadDescricaoMeses() {
    	if (!MESES_MAP.isEmpty()) {
    		return;
    	}
    	MESES_MAP.put(0, STR_MES_JANEIRO);
    	MESES_MAP.put(1, STR_MES_FEVEREIRO);
    	MESES_MAP.put(2, STR_MES_MARCO);
    	MESES_MAP.put(3, STR_MES_ABRIL);
    	MESES_MAP.put(4, STR_MES_MAIO);
    	MESES_MAP.put(5, STR_MES_JUNHO);
    	MESES_MAP.put(6, STR_MES_JULHO);
    	MESES_MAP.put(7, STR_MES_AGOSTO);
    	MESES_MAP.put(8, STR_MES_SETEMBRO);
    	MESES_MAP.put(9, STR_MES_OUTUBRO);
    	MESES_MAP.put(10, STR_MES_NOVEMBRO);
    	MESES_MAP.put(11, STR_MES_DEZEMBRO);
    }

    /**
     * Adiciona a hora atual na data passado como parametro.
     *
     * @param data - Data a receber a hora.
     * @return Data com a hora.
     */
    public static Date adicionarHoraAtualEmData(Date data) {
		Calendar horaAtual = GregorianCalendar.getInstance();
		horaAtual.setTime(new Date());

    	Calendar parametroGregorian = GregorianCalendar.getInstance();
		parametroGregorian.setTime(data);
		parametroGregorian.set(Calendar.HOUR, horaAtual.get(Calendar.HOUR));
		parametroGregorian.set(Calendar.MINUTE, horaAtual.get(Calendar.MINUTE));
		parametroGregorian.set(Calendar.SECOND, horaAtual.get(Calendar.SECOND));

    	return parametroGregorian.getTime();
    }


    /**
     * Valida se a data passada como parâmetro é menor que a data atual.
     * @param data - Data a ser validada.
     * @return Verdadeiro caso a data passada como parâmetro seja menor que a atual.
     */
    public static boolean isMenorDataAtual(Date data) {
    	Date dataAtual = criarDataAtualSemHora();
    	return dataAtual.compareTo(data) > 0;
    }

    /**
     * Retorna a data passada sem a mascara. O formato da string é informado pela constante
     * FORMATO_DATA_HORA_SEM_SEPARADORES
     *
     * @param data Data a ser transformada.
     *
     * @return String com a data passada sem mascara e no formato da constante
     * FORMATO_DATA_HORA_SEM_SEPARADORES
     */
    public static String getDataHoraSemSeparadores(Date data){
        DateFormat dateFormat = new SimpleDateFormat(FORMATO_DATA_HORA_SEM_SEPARADORES);

        return dateFormat.format(data);
    }
    
    /**
     * Retorna a data passada sem a mascara. O formato da string é informado pela constante
     * FORMATO_DATA_SEM_SEPARADORES
     *
     * @param data Data a ser transformada.
     *
     * @return String com a data passada sem mascara e no formato da constante
     * FORMATO_DATA_SEM_SEPARADORES
     */
    public static String getDataSemSeparadores(Date data){
        DateFormat dateFormat = new SimpleDateFormat(FORMATO_DATA_SEM_SEPARADORES);

        return dateFormat.format(data);
    }
    
	/**
	 * Inicializa as variáveis de localização (CALENDAR_BRASIL e
	 * SIMPLE_DATE_FORMAT_BRASIL) e define os valores padrões de localização
	 * para o sistema.
	 *
	 * @since 1.0
	 */
	public static void init() {
		// Inicializa a instância de SIMPLE_DATE_FORMAT_BRASIL
		SIMPLE_DATE_FORMAT_BRASIL = new SimpleDateFormat("dd/MM/yyyy", LOCALE_BRASIL);
		SIMPLE_DATE_FORMAT_BRASIL.setTimeZone(TIME_ZONE_PADRAO_BRASIL);
	}

	/**
	 * Retorna o Locale para o Brasil.
	 *
	 * @since 1.0
	 * @return java.util.Locale
	 */
	public static Locale getLocaleBrasil() {
		return LOCALE_BRASIL;
	}

	/**
	 * Retorna o TimeZone padrão do Brasil.<br>
	 *
	 * @since 1.0
	 * @return java.util.TimeZone
	 */
	public static TimeZone getTimeZonePadraoBrasil() {
//		TimeZone.setDefault(TIME_ZONE_PADRAO_BRASIL);
		return TIME_ZONE_PADRAO_BRASIL;
	}

	/**
	 * Retorna uma instância de Calendar padrão para o Brasil.<br>
	 *
	 * @since 1.0
	 * @return java.util.Calendar
	 */
	public static Calendar getCalandarBrasil() {
		return Calendar.getInstance(TIME_ZONE_PADRAO_BRASIL, LOCALE_BRASIL);
	}

	/**
	 * Retorna uma instância de SimpleDateFormat padrão para o Brasil.<br>
	 *
	 * @since 1.0
	 * @return java.text.SimpleDateFormat
	 */
	public static SimpleDateFormat getSimpleDateFormatBrasil() {
		if (SIMPLE_DATE_FORMAT_BRASIL == null) {
			SIMPLE_DATE_FORMAT_BRASIL = new SimpleDateFormat("dd/MM/yyyy", LOCALE_BRASIL);
		}
		if (SIMPLE_DATE_FORMAT_BRASIL.getTimeZone() != TIME_ZONE_PADRAO_BRASIL) {
			SIMPLE_DATE_FORMAT_BRASIL.setTimeZone(TIME_ZONE_PADRAO_BRASIL);
		}
		return SIMPLE_DATE_FORMAT_BRASIL;
	}

	/**
	 * Retorna a formatação de hora.
	 *
	 * @since 2.1
	 * @return
	 */
	public static SimpleDateFormat getSimpleDateFormatHora() {
		return new SimpleDateFormat("HH:mm", LOCALE_BRASIL);
	}

	/**
	 * Retorna a formatação de hora completa.
	 *
	 * @since 2.1
	 * @return
	 */
	public static SimpleDateFormat getSimpleDateFormatHoraCompleta() {
		return new SimpleDateFormat("HH:mm:ss", LOCALE_BRASIL);
	}

	/**
	 * Retorna a formatação de hora completa.
	 *
	 * @since 2.1
	 * @return
	 */
	public static SimpleDateFormat getSimpleDateFormatDataHora() {
		return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", LOCALE_BRASIL);
	}

	/**
	 * Adiciona dias a data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdDias
	 * @return A data modificada
	 */
	public static Date incrementaDias(Date _date, int _qtdDias) {
		return changeTime(_date, _qtdDias, Calendar.DAY_OF_MONTH, INCREMENTO);
	}

	/**
	 * Adiciona meses a data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdMeses
	 * @return A data modificada
	 */
	public static Date incrementaMeses(Date _date, int _qtdMeses) {
		return changeTime(_date, _qtdMeses, Calendar.MONTH, INCREMENTO);
	}

	/**
	 * Adiciona anos a data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdAnos
	 * @return A data modificada
	 */
	public static Date incrementaAnos(Date _date, int _qtdAnos) {
		return changeTime(_date, _qtdAnos, Calendar.YEAR, INCREMENTO);
	}

	/**
	 * Adiciona horas a data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdHoras
	 * @return A data modificada
	 */
	public static Date incrementaHoras(Date _date, int _qtdHoras) {
		return changeTime(_date, _qtdHoras, Calendar.HOUR, INCREMENTO);
	}

	/**
	 * Adiciona minutos a data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdMinutos
	 * @return A data modificada
	 */
	public static Date incrementaMinutos(Date _date, int _qtdMinutos) {
		return changeTime(_date, _qtdMinutos, Calendar.MINUTE, INCREMENTO);
	}

	/**
	 * Adiciona segundos a data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdSegundos
	 * @return A data modificada
	 */
	public static Date incrementaSegundos(Date _date, int _qtdSegundos) {
		return changeTime(_date, _qtdSegundos, Calendar.SECOND, INCREMENTO);
	}

	/**
	 * Remove dias da data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdDias
	 * @return A data modificada
	 */
	public static Date decrementaDia(Date _date, int _qtdDias) {
		return changeTime(_date, _qtdDias, Calendar.DAY_OF_MONTH, DECREMENTO);
	}

	/**
	 * Remove meses da data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdMeses
	 * @return A data modificada
	 */
	public static Date decrementaMeses(Date _date, int _qtdMeses) {
		return changeTime(_date, _qtdMeses, Calendar.MONTH, DECREMENTO);
	}

	/**
	 * Remove anos da data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdAnos
	 * @return A data modificada
	 */
	public static Date decrementaAnos(Date _date, int _qtdAnos) {
		return changeTime(_date, _qtdAnos, Calendar.YEAR, DECREMENTO);
	}

	/**
	 * Remove horas da data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdHoras
	 * @return A data modificada
	 */
	public static Date decrementaHoras(Date _date, int _qtdHoras) {
		return changeTime(_date, _qtdHoras, Calendar.HOUR, DECREMENTO);
	}

	/**
	 * Remove minutos da data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdMinutos
	 * @return A data modificada
	 */
	public static Date decrementaMinutos(Date _date, int _qtdMinutos) {
		return changeTime(_date, _qtdMinutos, Calendar.MINUTE, DECREMENTO);
	}

	/**
	 * Remove segundos da data
	 *
	 * @since 1.0
	 * @param _date
	 * @param _qtdSegundos
	 * @return A data modificada
	 */
	public static Date decrementaSegundos(Date _date, int _qtdSegundos) {
		return changeTime(_date, _qtdSegundos, Calendar.SECOND, DECREMENTO);
	}

	/**
	 * Altera a data(em long)
	 *
	 * @since 1.0
	 * @param _time
	 * @param _qtde
	 * @param _intervalo
	 * @param _acao
	 * @return A data modificada
	 */
	private static Date changeTime(Date date, int _qtde, int _intervalo, int _acao) {
		Calendar cal = new GregorianCalendar();
                cal.setTime(date);
                switch(_acao){
                    case INCREMENTO:
                        cal.add(_intervalo, +_qtde);
                        break;
                    case DECREMENTO:
                        cal.add(_intervalo, -_qtde);
                        break;
                }
                return cal.getTime();
	}

	/**
	 * Altera a data(em long)
	 *
	 * @since 1.0
	 * @param _time
	 * @param _milesAltera
	 * @param _acao
	 * @return A data modificada
	 */
	public static long setMilesNewDate(long _time, long _milesAltera, int _acao) {
		switch (_acao) {
		case INCREMENTO:
			_time += _milesAltera;
			break;
		case DECREMENTO:
			_time -= _milesAltera;
			break;
		default:
			_time = -1;
		}
		return _time;
	}

	/**
	 * Retorna a quantodade de milisegundos do ano
	 *
	 * @since 1.0
	 * @param _time
	 * @param _qtdAnos
	 * @param _acao
	 * @return O total de milisegunos do ano
	 */
	public static long getTotalMilesYears(long _time, int _qtdAnos, int _acao) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new java.util.Date(_time));
		int anoData = calendar.get(Calendar.YEAR);
		int mesInicialAnoData = calendar.get(Calendar.MONTH);
		int totalDiasAnos = 0;
		boolean controleAnoAtualBi = false;
		for (int i = 0; i < _qtdAnos; i++) {
			int diasNovoAno = getDiasAno(getNovoAno((i + 1), anoData, _acao));
			if (!controleAnoAtualBi) {
				if (isAnoBisexto(anoData) && (_acao == INCREMENTO) && (mesInicialAnoData < 1)) {
					diasNovoAno++;
				}
				if (isAnoBisexto(anoData) && (_acao == DECREMENTO) && (mesInicialAnoData > 1) && ((_qtdAnos % 4) != 0)) {
					diasNovoAno++;
				}
				controleAnoAtualBi = true;
			}
			totalDiasAnos += diasNovoAno;
		}
		long totalMilesAnos = totalDiasAnos * (24L * 60L * 60L * 1000L);
		return totalMilesAnos;
	}

	/**
	 * Retorna a quantodade de milisegundos do mes
	 *
	 * @since 1.0
	 * @param _time
	 * @param _qtdMeses
	 * @param _acao
	 * @return O total de milisegunos do mes
	 */
	public static long getTotalMilesMonths(long _time, int _qtdMeses, int _acao) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new java.util.Date(_time));
		int mesInicial = calendar.get(Calendar.MONTH);
		YearValue ano = new YearValue();
		int totalDiasMeses = 0;
		for (int i = 0; i < _qtdMeses; i++) {
			ano.value = calendar.get(Calendar.YEAR);
			totalDiasMeses += getDiasMes(getNovoMes((i), mesInicial, ano, _acao), ano.value);
		}
		long totalMilesMeses = totalDiasMeses * (24L * 60L * 60L * 1000L);
		return totalMilesMeses;
	}

	/**
	 * @since 1.0
	 * @param _fator
	 * @param _mesInicial
	 * @param _ano
	 * @param _acao
	 * @return O novo mes
	 */
	private static int getNovoMes(int _fator, int _mesInicial, YearValue _ano, int _acao) {
		int mes = -1;
		switch (_acao) {
		case INCREMENTO:
			mes = _mesInicial + _fator;
			int resultado = -1;
			int controle = 0;
			if (mes > 11) {
				resultado = mes - 12;
				controle = 1;
				_ano.value += 1;
				while (resultado > 11) {
					resultado -= 12;
					controle++;
					_ano.value += 1;
				}
				mes -= (12 * controle);
			}
			break;
		case DECREMENTO:
			mes = _mesInicial - _fator;
			resultado = -1;
			controle = 0;
			if (mes < 0) {
				resultado = mes + 12;
				controle = 1;
				_ano.value -= 1;
				while (resultado < 0) {
					resultado += 12;
					controle++;
					_ano.value -= 1;
				}
				mes += (12 * controle);
			}
			break;
		default:
			mes = -1;
		}
		return mes;
	}

	/**
	 * @since 1.0
	 * @param _fator
	 * @param _anoInicial
	 * @param _acao
	 * @return O novo ano
	 */
	private static int getNovoAno(int _fator, int _anoInicial, int _acao) {
		int ano = -1;
		switch (_acao) {
		case INCREMENTO:
			ano = _anoInicial + _fator;
			break;
		case DECREMENTO:
			ano = _anoInicial - _fator;
			break;
		default:
			ano = -1;
		}
		return ano;
	}

	/**
	 * Retorna a quantidade de dias do ano
	 *
	 * @since 1.0
	 * @param _ano
	 * @return A quantidade de dias do ano
	 */
	public static int getDiasAno(int _ano) {
		if (isAnoBisexto(_ano)) {
			return 366;
		}
		return 365;
	}

	/**
	 * Dados os inteiros representando respectivamente um mês e um ano, retorna
	 * número de dias do mês informado.<br>
	 *
	 * @since 1.0
	 * @param _mes
	 * @param _ano
	 * @return A quantidade de dias no mes
	 */
	public static int getDiasMes(int _mes, int _ano) {
		int numDiasMes = 0;
		switch (_mes) {
		case JANEIRO:
		case MARCO:
		case MAIO:
		case JULHO:
		case AGOSTO:
		case OUTUBRO:
		case DEZEMBRO:
			numDiasMes = 31;
			break;
		case ABRIL:
		case JUNHO:
		case SETEMBRO:
		case NOVEMBRO:
			numDiasMes = 30;
			break;
		case FEVEREIRO:
			if (isAnoBisexto(_ano)) {
				numDiasMes = 29;
			} else {
				numDiasMes = 28;
			}
			break;
		default:
			numDiasMes = -1;
		}
		return numDiasMes;
	}

	/**
	 * Retorna o número de dias do mês da data informada.
	 *
	 * @param _data
	 * @return A quantidade de dias no mes
	 */
	public static int getDiasMes(java.util.Date _data) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(_data);
		return getDiasMes(Calendar.MONTH, Calendar.YEAR);
	}

	/**
	 * Retorna verdadeiro se o objeto Date <tt>_data</tt> representar um ano
	 * bisexto.<br>
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o ano seja bissexto, falso caso contrario
	 */
	public static boolean isAnoBisexto(java.util.Date _data) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(_data);
		return isAnoBisexto(calendar.get(Calendar.YEAR));
	}

	/**
	 * Retorna verdadeiro se o long <tt>_time</tt> representar o
	 * <strong>time</strong> de um objeto Date que cuja data seja a de um ano
	 * bisexto.<br>
	 *
	 * @since 1.0
	 * @param _tempo
	 * @return Verdadeiro caso o ano seja bissexto, falso caso contrario
	 */
	public static boolean isAnoBisexto(long _tempo) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new java.util.Date(_tempo));
		return isAnoBisexto(calendar.get(Calendar.YEAR));
	}

	/**
	 * Retorna verdadeiro se o int <tt>_ano</tt> representar um ano bisexto.<br>
	 *
	 * @since 1.0
	 * @param _ano
	 * @return Verdadeiro caso o ano seja bissexto, falso caso contrario
	 */
	public static boolean isAnoBisexto(int _ano) {
		if ((_ano % 4) == 0) {
			return true;
		}
		return false;
	}

	/**
	 * Verifica se o dia da data e domingo
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja domingo, falso caso contrario
	 */
	public static boolean isDomingo(Calendar _data) {
		return _data.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
	}

	/**
	 * Verifica se o dia da data e domingo
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja domingo, falso caso contrario
	 */
	public static boolean isDomingo(Date _data) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(_data);
		return isDomingo(calendar);
	}

	/**
	 * Verifica se o dia da data e segunda
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja segunda, falso caso contrario
	 */
	public static boolean isSegunda(Calendar _data) {
		return _data.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY;
	}

	/**
	 * Verifica se o dia da data e terca
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja terca, falso caso contrario
	 */
	public static boolean isTerca(Calendar _data) {
		return _data.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY;
	}

	/**
	 * Verifica se o dia da data e quarta
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja quarta, falso caso contrario
	 */
	public static boolean isQuarta(Calendar _data) {
		return _data.get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY;
	}

	/**
	 * Verifica se o dia da data e quinta
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja quinta, falso caso contrario
	 */
	public static boolean isQuinta(Calendar _data) {
		return _data.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY;
	}

	/**
	 * Verifica se o dia da data e sexta
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja sexta, falso caso contrario
	 */
	public static boolean isSexta(Calendar _data) {
		return _data.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY;
	}

	/**
	 * Verifica se o dia da data e sabado
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja sabado, falso caso contrario
	 */
	public static boolean isSabado(Calendar _data) {
		return _data.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY;
	}

	/**
	 * Verifica se o dia da data e sabado
	 *
	 * @since 1.0
	 * @param _data
	 * @return Verdadeiro caso o dia seja sabado, falso caso contrario
	 */
	public static boolean isSabado(Date _data) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(_data);
		return isSabado(calendar);
	}

	/**
	 * Retorna a data formatada.
	 *
	 * @param _data
	 * @return Date construido a partir de uma máscara dd/mm/yyyy
	 */
	public static Date getDataValida(String _data)  {
		if (isDataValida(_data)) {
			SimpleDateFormat dateFormat = getSimpleDateFormatBrasil();
			try {
				return dateFormat.parse(_data);
			} catch (ParseException e) {
				return null;//(e.getMessage());
			}
		}
		return null;
	}

	/**
	 * Retorna a data formatada com horas.
	 *
	 * @param dataHoraProducaoConteudo
	 * @return Date construido a partir de uma máscara dd/mm/yyyy HH:MM:SS
	 */
	public static Date getData(String _dataHoraProducaoConteudo)  {
		if (isDataHoraValida(_dataHoraProducaoConteudo)) {
			SimpleDateFormat dateFormat = getSimpleDateFormatDataHora();
			try {
				return dateFormat.parse(_dataHoraProducaoConteudo);
			} catch (ParseException e) {
				return null;//(e.getMessage());
			}
		}
		return null;
	}

	/**
	 * Retorna a data informada no formato dd/mm/yyyy
	 *
	 * @param _data
	 * @return
	 * @throws InvalidDateException
	 */
	public static Date getData(Date _data)  {
            try{
                DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
                return df.parse(df.format(_data));
            } catch (ParseException ex) {
                return null;
            }
	}

	/**
	 * Valida se a Data/Hora é válida.
	 *
	 * @param _dataHora
	 * @return
	 */
	public static Boolean isDataHoraValida(String _dataHora)  {
		int dia = 0;
		int mes = 1;
		int ano = 2;
		int hora = 3;
		int minuto = 4;
		int segundo = 5;

		String strData = _dataHora.replaceAll("[/]|[:]|[\\s]", ".");
		String[] campos = strData.split("\\.");

		if (campos.length != 6) {
			return false;
		}

		if (campos[ano].length() < 4 || Integer.parseInt(campos[ano]) == 0 || Integer.parseInt(campos[ano]) < 1900) {
			return false;//("Ano Inválido");
		}

		if (campos[mes].length() < 2 || Integer.parseInt(campos[mes]) > 12 || Integer.parseInt(campos[mes]) == 0) {
			return false;//("Mês Inválido");
		}

		if (campos[dia].length() < 2
				|| (Integer.parseInt(campos[mes]) == 4 || Integer.parseInt(campos[mes]) == 6
						|| Integer.parseInt(campos[mes]) == 9 || Integer.parseInt(campos[mes]) == 11)
				&& Integer.parseInt(campos[dia]) > 30) {
			return false;//("Dia Inválido");
		}

		if (Integer.parseInt(campos[dia]) > 31 || Integer.parseInt(campos[mes]) == 0) {
			return false;//("Dia Inválido");
		}

		if (!isAnoBisexto(Integer.parseInt(campos[ano])) && Integer.parseInt(campos[mes]) == 2
				&& Integer.parseInt(campos[dia]) > 28) {
			return false;//("Dia Inválido");
		}

		if (isAnoBisexto(Integer.parseInt(campos[ano])) && Integer.parseInt(campos[mes]) == 2
				&& Integer.parseInt(campos[dia]) > 29) {
			return false;//("Dia Inválido");
		}

		validaHora(hora, minuto, segundo, campos);

		return true;
	}

	/**
	 * Valida se a Data/Hora é válida.
	 *
	 * @param _data
	 * @return
	 */
	public static Boolean isDataValida(String _data)  {
		int dia = 0;
		int mes = 1;
		int ano = 2;

		String strData = _data.replaceAll("[/]|[:]|[\\s]", ".");
		String[] campos = strData.split("\\.");

		if (campos.length != 3) {
			return false;//("Data Inválida");
		}

		if (campos[ano].length() < 4 || Integer.parseInt(campos[ano]) == 0 || Integer.parseInt(campos[ano]) < 1900) {
			return false;//("Ano Inválido");
		}

		if (campos[mes].length() < 2 || Integer.parseInt(campos[mes]) > 12 || Integer.parseInt(campos[mes]) == 0) {
			return false;//("Mês Inválido");
		}

		if (campos[dia].length() < 2
				|| (Integer.parseInt(campos[mes]) == 4 || Integer.parseInt(campos[mes]) == 6
						|| Integer.parseInt(campos[mes]) == 9 || Integer.parseInt(campos[mes]) == 11)
				&& Integer.parseInt(campos[dia]) > 30) {
			return false;//("Dia Inválido");
		}

		if (Integer.parseInt(campos[dia]) > 31 || Integer.parseInt(campos[mes]) == 0) {
			return false;//("Dia Inválido");
		}

		if (!isAnoBisexto(Integer.parseInt(campos[ano])) && Integer.parseInt(campos[mes]) == 2
				&& Integer.parseInt(campos[dia]) > 28) {
			return false;//("Dia Inválido");
		}

		if (isAnoBisexto(Integer.parseInt(campos[ano])) && Integer.parseInt(campos[mes]) == 2
				&& Integer.parseInt(campos[dia]) > 29) {
			return false;//("Dia Inválido");
		}

		return true;
	}

	/**
	 * Valida a hora.
	 *
	 * @param _hora
	 * @param _minuto
	 * @param _segundo
	 * @param _campos
	 */
	private static boolean validaHora(int _hora, int _minuto, int _segundo, String[] _campos)  {
		try {
			if (_campos[_hora].length() < 2 || Integer.parseInt(_campos[_hora]) > 24) {
				return false;//("Hora Inválida");
			}

			if (_campos[_minuto].length() < 2 || Integer.parseInt(_campos[_minuto]) > 60) {
				return false;//("Minuto Inválido");
			}

			if (Integer.parseInt(_campos[_hora]) == 24 && Integer.parseInt(_campos[_minuto]) == 60) {
				return false;//("Minuto Inválido");
			}

			if (_campos[_segundo].length() < 2 || Integer.parseInt(_campos[_segundo]) > 60) {
				return false;//("Segundo Inválido");
			}
		} catch (NumberFormatException e) {
			return false;//("Hora inválida");
		}
                return true;
	}

	/**
	 *
	 * @param _data
	 *            no formato dd/mm/yyyy
	 * @return o mês de forma lietaral.
	 */
	public static String literalMes(String _data) {

		String literal = "";
		switch (mesData(_data) - 1) {
		case Calendar.JANUARY:
			literal = "janeiro";
			break;
		case Calendar.FEBRUARY:
			literal = "fevereiro";
			break;
		case Calendar.MARCH:
			literal = "março";
			break;
		case Calendar.APRIL:
			literal = "abril";
			break;
		case Calendar.MAY:
			literal = "maio";
			break;
		case Calendar.JUNE:
			literal = "junho";
			break;
		case Calendar.JULY:
			literal = "julho";
			break;
		case Calendar.AUGUST:
			literal = "agosto";
			break;
		case Calendar.SEPTEMBER:
			literal = "setembro";
			break;
		case Calendar.OCTOBER:
			literal = "outubro";
			break;
		case Calendar.NOVEMBER:
			literal = "novembro";
			break;
		case Calendar.DECEMBER:
			literal = "dezembro";
			break;
		}

		return literal;
	}

	/**
	 * Retorna o dia da data passado como parâmetro.
	 *
	 * @param _data
	 *            no formato dd/mm/yyyy
	 * @return dia da data informada.
	 */
	public static Integer diaData(String _data) {
		return new Integer(_data.substring(0, 2));
	}

	/**
	 * Retorna o dia da data passado como parâmetro.
	 *
	 * @param _data
	 * @return dia da data informada.
	 */
        public static int diaData(Date data) {
            Calendar cal = getCalandarBrasil();
            cal.setTime(data);
            return cal.get(Calendar.DAY_OF_MONTH);
        }

	/**
	 * Retorna o mês da data passado como parâmetro.
	 *
	 * @param _data
	 *            no formato dd/mm/yyyy
	 * @return mês da data informada
	 */
	public static Integer mesData(String _data) {
		return new Integer(_data.substring(3, 5));
	}

	/**
	 * Retorna o ano do data passado como parâmetro.
	 *
	 * @param _data
	 *            no formato dd/mm/yyyy
	 * @return ano da data informada
	 */
	public static Integer anoData(String _data) {
		return new Integer(_data.substring(6, 10));
	}

	/**
	 * Retorna a data atual no formato de texto.
	 *
	 * @return a data atual no formato dd de mes de aaaa
	 */
	public static String getDataAtualTexto() {

		String data = getDataFormatoString(getDataAtual());
		return diaData(data) + " de " + literalMes(data) + " de " + anoData(data);
	}

	/**
	 * @return Retorna a data e hora atual no formato de dd/MM/yyyy HH:mm:ss
	 */
	public static String getDataHoraAtualString() {
		return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(getDataAtual());
	}

	/**
	 * @return Retorna a data e hora atual no formato informado.
	 */
	public static String getDataHoraAtualString(String _formato) {
		return new SimpleDateFormat(_formato).format(getDataAtual());
	}

	/**
	 * Retorna a data atual na última hora do dia.
	 *
	 * @return dataAtual Date.
	 */
	public static Date getDataAtualUltimaHora() {
		String dataAtual = new SimpleDateFormat(HORA_INICIO_DIA).format(getDataAtual());
		return parseData(dataAtual, DATA_HORA);
	}

	/**
	 * Retorna a data atual na priveira hora do dia.
	 *
	 * @return dataAtual Date.
	 */
	public static Date getDataAtualPrimeiraHora() {
		return getDataPrimeiraHoraDia(getDataAtual());
	}

	/**
	 * @return Retorna a data no formato dd/mm/yyyy.
	 */
	public static String getDataFormatoString(Date _data) {
		return new SimpleDateFormat("dd/MM/yyyy").format(_data);
	}

	/**
	 * @return Retorna a data no formato dd/mm/yyyy.
	 */
	public static String getDataFormatoString(Date _data, String formato) {
		return new SimpleDateFormat(formato).format(_data);
	}

	/**
	 * Obtem o ano da _data e converte para String.
	 *
	 * @param _data
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static String converteParaAno(Date _data) {
		return _data.getYear() + "";
	}

	/**
	 * @return Retorna a data atual do sistema.
	 */
	public static Date getDataZero() {
		try {
			return getSimpleDateFormatBrasil().parse("01/01/1500");
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * Retorna uma data informada para as 23:59:59 da data passada
	 *
	 * @param _data
	 * @return
	 */
	public static Date getDataUltimaHoraDia(Date _data) {
		Calendar calendario = new GregorianCalendar();

		calendario.setTime(_data);
		calendario.set(Calendar.HOUR_OF_DAY, 23);
		calendario.set(Calendar.MINUTE, 59);
		calendario.set(Calendar.SECOND, 59);
		return calendario.getTime();
	}

	/**
	 * Retorna uma data informada para as 00:00:00 da data passada
	 *
	 * @param _data
	 * @return
	 */
	public static Date getDataPrimeiraHoraDia(Date _data) {
		Calendar calendario = new GregorianCalendar();

		calendario.setTime(_data);
		calendario.set(Calendar.HOUR_OF_DAY, 00);
		calendario.set(Calendar.MINUTE, 00);
		calendario.set(Calendar.SECOND, 01);
		return calendario.getTime();
	}

	/**
	 * Verifica se a data é um final de semana.
	 *
	 * @param _data
	 * @return
	 */
	public static Boolean isFinalDeSemana(Date _data) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(_data);
		return isSabado(calendar) || isDomingo(calendar);
	}

	/**
	 * Forma a data recebida no tipo string para o tipo Date.
	 *
	 * @param data
	 *            no formato dd/MM/yyyy
	 *
	 * @return Data formatada para o tipo Date.
	 */
	public static Date formataDataSimples(Date data) {

		try {
			String dataSimples = FORMATO_DATA_SIMPLES.format(data);
			return FORMATO_DATA_SIMPLES.parse(dataSimples);
		} catch (ParseException e) {
			return null;
		}
	}


    public static int getMesAtual(){
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(new Date());
        return calendar.get(Calendar.MONTH)+1;
    }

    public static int getDiaAtual(){
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(new Date());
        return calendar.get(Calendar.DAY_OF_MONTH);
    }
    
    public static  int getDiaSemana(int ano, int mes, int dia){
        Calendar calendario = new GregorianCalendar(ano, mes - 1, dia);
        return calendario.get(Calendar.DAY_OF_WEEK);
    }
    public static String getDiaSemanaAtual(){
    	int dia = getDiaSemana(getAnoAtual(), getMesAtual(), getDiaAtual());
    	return String.valueOf(dia);
    }
    @SuppressWarnings("deprecation")
	public static String getDiaSemanaAtual(Date date){
    	int dia = getDiaSemana(date.getDay(),date.getMonth(),date.getDay());
    	return String.valueOf(dia);
    }
    public static int getDiaSemanaAtualNum(){
    	int dia = getDiaSemana(getAnoAtual(), getMesAtual(), getDiaAtual());
    	return dia;
    }
    
    /**
	 * Retorna String correspondente ao dia da semana
	 *
	 * @param 
	 *
	 * @return Strign .
	 */
//    
//    public static String getDiaAtual(){
//    	Calendar calendar = new GregorianCalendar();
//        calendar.setTime(new Date());
//        calendar.get(Calendar.DAY_OF_MONTH);
//        return null;
//    }
    public static class Mes {
        int mes;
        int ano;

        public Mes(int mes, int ano) {
            this.mes = mes;
            this.ano = ano;
        }

        public Date getPrimeiroDia(){
            return DateUtil.getPrimeiroDiaDoMes(mes, ano);
        }

        public boolean after(Mes mes){
            return getPrimeiroDia().after(mes.getPrimeiroDia());
        }

        public boolean before(Mes mes){
            return getPrimeiroDia().before(mes.getPrimeiroDia());
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Mes){
                Mes other = (Mes) obj;
                return getMes()==other.getMes() && getAno()==other.getAno();
            }
            return false;
        }

        public int getAno() {
            return ano;
        }

        public void setAno(int ano) {
            this.ano = ano;
        }

        public int getMes() {
            return mes;
        }

        public void setMes(int mes) {
            this.mes = mes;
        }
        
        
        
    }

	public static boolean isAnoValido(String data) {
		int ano;
		try {
			ano = Integer.parseInt(data);
		} catch (NumberFormatException e) {
			e.printStackTrace();
			return false;
		}
		if(ano < 1800 || ano > DateUtil.getAnoAtual()){
			return false;
		}
		return true;
	}

	@SuppressWarnings("deprecation")
	public static boolean isPeriodoValido(Date dateInicio, Date dateFim) {
		isDataIgual(dateInicio, dateFim);
		
		if(dateInicio.getDate() > dateFim.getDate()){ 
			return true;
		}
		return false;
	}

	public static boolean isDataIgualMesAno(String data, String data2) {
		
		if(data2.contains(data))
			return true;			
		return false;
	}

	public static String getDiaSemanaAtualExt(java.sql.Date date) {
		String numDia = getDiaSemanaAtual(date);
		return parseDiaSemanaExt(numDia);
	}

	private static String parseDiaSemanaExt(String numDia) {
		Integer num = 0;
		try{		
		num = Integer.parseInt(numDia);
		}catch(NumberFormatException e){
			e.printStackTrace();
		}
		switch (num) {
		case 1:
			return STR_DOMINGO;
		case 2:
			return STR_SEGUNDA_FEIRA;
		case 3:
			return STR_TERCA_FEIRA;
		case 4:
			return STR_QUARTA_FEIRA;
		case 5:
			return STR_QUINTA_FEIRA;
		case 6:
			return STR_SEXTA_FEIRA;
		case 7:
			return STR_SABADO;
		}
		return numDia;
	}
	
	public static String formatDateIn(String data){
		String date[] = data.split("/");
		return date[2]+"-"+date[1]+"-"+date[0];
	}

	public static String formatDateOut(String data){
		String date[] = data.split("-");
		return date[2]+"/"+date[1]+"/"+date[0];
	}
}

/**
 * @author Manoel Veríssimo
 * @since 1.0
 * @version 1.0
 */
class YearValue {
	/**
	 * @since 1.0
	 */
	int value;
}

